Open Asset Protocol (アセットの発行)
Asset Definition Protocolについて
Asset IDによりアセットを一意に識別することはできるが、そのアセットがどんなアセットで誰が発行者なのかはブロックチェーン上に記録されてない。アセットに関する方法や付加条件を定義したAsset Definitionをブロックチェーン外で公開し、ブロックチェーン上のアセットと関連付けるしくみがAsset Definition Protocol。
アセットの発行者はAsset Definition Pointerという文字列を使ってメタデータのファイルとアセットをブロックチェーン
上で関連づける
このAsset Definition Pointerの定義が3つあって、ブロックチェーン と関連づける方法が2つある
(ややこしいので、関連付けのお話だけします。定義の説明は:バイブルを読んでください。) <関連付け>
方法1.アセット作成時にMareker OutputのmetadataフィールドにAsset Definition Pointerを記載する。
一般的
同じAsset IDのアセットを再度発行する際に、以前発行したAsset Definition Pointerとは異なるAsset Definition Pointerを付与することができる。
方法2.P2SHをつかってアセットを発行し、そのredeem Script 内にAsset Definition Pointerを記載する。
異なるAsset Definition Pointerを使うと別のAsset IDのアセットになる。
code:方法2
<Asset Definition Pointer> OP_DROP 残りのスクリプト
Asset Definition Pointerは以下のフローに従って決定される
1.アセットの発行トランザクションの最初のインプットが参照するアウトプットスクリプトがP2PSHである。
2.そのスクリプトの元になったredeem Script のスクリプトがPUSHDATAからはじまり、その後のOP_DROPが続く
3.PUSHDATAのペイロードが有効な Asset Definition Pointerである
(これがすべてtrueなら、ペイロードがAsset Definition Pointerになる)
さて、このようにしてAsset Definition Pointerが決まると、そこに含まれているURLにアクセスしAsset Definition Fileを入手する
(Asset Definition PointerにハッシュがあればAsset Definition Fileのハッシュと照合する)
このAsset Definition Fileにはアセットの名称や量、Asset IDなどのメタデータがJSONで記述してある
アセットの発行
code:設定
require 'bitcoin'
require 'openassets'
require 'pp'
require 'json'
include Bitcoin::Util
Bitcoin.network = :testnet3
oa_api = OpenAssets::Api.new({:network => 'testnet',
:provider => 'bitcoind', :cache => 'testnet.db',
:dust_limit => 600, :default_fees => 10000,
:min_confirmation => 0, :max_confirmation => 9999999,
:rpc => {:user => 'user', :password => 'password', :schema => 'http',
:port => 18332, :host => 'localhost'}})
code:発行
btc_address = "2N3PGzfcupV2xPAt3AQhRizR8BMENktau7q"
oa_address = OpenAssets.address_to_oa_address(btc_address)
code:送金
> tx = Bitcoin::Protocol::Tx.new
> prev_tx_hash = "07a7b668feaef629772096423274f0568539774848a7691dc98dacdb2552bdf7"
=> "07a7b668feaef629772096423274f0568539774848a7691dc98dacdb2552bdf7"
> prev_output_index = 2
=> 2
> tx_in = Bitcoin::Protocol::TxIn.from_hex_hash(prev_tx_hash, prev_output_index)
@prev_out_hash="\xF7\xBDR%\xDB\xAC\x8D\xC9\x1Di\xA7HHw9\x85V\xF0t2B\x96 w)\xF6\xAE\xFEh\xB6\xA7\a", @prev_out_index=2, @script_sig_length=0, @script_sig="", @sequence="\xFF\xFF\xFF\xFF", @script_witness=#<Bitcoin::Protocol::ScriptWitness:0x00007f8e0668ee58 @stack=[]>>
> tx.add_in(tx_in)
=> [#<Bitcoin::Protocol::TxIn:0x00007f8e0668ef20
@prev_out_hash="\xF7\xBDR%\xDB\xAC\x8D\xC9\x1Di\xA7HHw9\x85V\xF0t2B\x96 w)\xF6\xAE\xFEh\xB6\xA7\a", @prev_out_index=2, @script_sig_length=0, @script_sig="", @sequence="\xFF\xFF\xFF\xFF", @script_witness=#<Bitcoin::Protocol::ScriptWitness:0x00007f8e0668ee58 @stack=[]>>]
> script = OpenAssets::Protocol::MarkerOutput.new(10, 30) > script = OpenAssets::Protocol::MarkerOutput.new(10, 30).build_script @input_script="j\bOA\x01\x00\x02\n\x1E\x00", @parse_invalid=nil, @inner_p2sh=nil, @script_codeseparator_index=nil, @raw="j\bOA\x01\x00\x02\n\x1E\x00", @chunks=106, "OA\x01\x00\x02\n\x1E\x00", @exec_stack=[], @stack_alt=[], @stack=[], @last_codeseparator_index=0, @do_exec=true> > tx.add_out(Bitcoin::Protocol::TxOut.new(0, script.to_payload))
> tx_out1 = Bitcoin::Protocol::TxOut.value_to_address(600, "2NAnNzyjoimUv5zmK2aETrs5GCoo39jnX3v")
> tx_out2 = Bitcoin::Protocol::TxOut.value_to_address(600, "2N6569NW3hYBMqbQ5EUovx2H3PCdjeWNwje")
> tx.add_out(tx_out1)
> tx.add_out(tx_out2)
> tx_in1 = Bitcoin::Protocol::TxIn.from_hex_hash("07a7b668feaef629772096423274f0568539774848a7691dc98dacdb2552bdf7", 3)
=> #<Bitcoin::Protocol::TxIn:0x00007f8e0706a788 @prev_out_hash="\xF7\xBDR%\xDB\xAC\x8D\xC9\x1Di\xA7HHw9\x85V\xF0t2B\x96 w)\xF6\xAE\xFEh\xB6\xA7\a", @prev_out_index=3, @script_sig_length=0, @script_sig="", @sequence="\xFF\xFF\xFF\xFF", @script_witness=#<Bitcoin::Protocol::ScriptWitness:0x00007f8e0706a6c0 @stack=[]>> > tx.add_in(tx_in1)
=> [#<Bitcoin::Protocol::TxIn:0x00007f8e0668ef20 @prev_out_hash="\xF7\xBDR%\xDB\xAC\x8D\xC9\x1Di\xA7HHw9\x85V\xF0t2B\x96 w)\xF6\xAE\xFEh\xB6\xA7\a", @prev_out_index=2, @script_sig_length=0, @script_sig="", @sequence="\xFF\xFF\xFF\xFF", @script_witness=#<Bitcoin::Protocol::ScriptWitness:0x00007f8e0668ee58 @stack=[]>>, #<Bitcoin::Protocol::TxIn:0x00007f8e0706a788 @prev_out_hash="\xF7\xBDR%\xDB\xAC\x8D\xC9\x1Di\xA7HHw9\x85V\xF0t2B\x96 w)\xF6\xAE\xFEh\xB6\xA7\a", @prev_out_index=3, @script_sig_length=0, @script_sig="", @sequence="\xFF\xFF\xFF\xFF", @script_witness=#<Bitcoin::Protocol::ScriptWitness:0x00007f8e0706a6c0 @stack=[]>>] > tx.to_payload.bth
=> "0100000002f7bd5225dbac8dc91d69a7484877398556f074324296207729f6aefe68b6a7070200000000fffffffff7bd5225dbac8dc91d69a7484877398556f074324296207729f6aefe68b6a7070300000000ffffffff0300000000000000000a6a084f410100020a1e00580200000000000017a914c05e8e53c28ba0404f2945478fd155a353c4e15187580200000000000017a9148caeeda504d75d0c8759c1fc73fa3120c836201e8700000000"
> OpenAssets::Protocol::MarkerOutput.deserialize_payload("4f410100020a1e00")
> tx_out3 = Bitcoin::Protocol::TxOut.value_to_address(995000, "2N6569NW3hYBMqbQ5EUovx2H3PCdjeWNwje")
> tx.add_out(tx_out3)
=> #<Bitcoin::Protocol::TxOut:0x00007f8e0691e060 @value=0, @pk_script_length=10, @pk_script="j\bOA\x01\x00\x02\n\x1E\x00">, #<Bitcoin::Protocol::TxOut:0x00007f8e05bb06f8 @value=600, @pk_script_length=23, @pk_script="\xA9\x14\xC0^\x8ES\xC2\x8B\xA0@O)EG\x8F\xD1U\xA3S\xC4\xE1Q\x87">, #<Bitcoin::Protocol::TxOut:0x00007f8e0708b190 @value=600, @pk_script_length=23, @pk_script="\xA9\x14\x8C\xAE\xED\xA5\x04\xD7\f\x87Y\xC1\xFCs\xFA1 \xC86 \x1E\x87">, #<Bitcoin::Protocol::TxOut:0x00007f8e0690fdd0 @value=995000, @pk_script_length=23, @pk_script="\xA9\x14\x8C\xAE\xED\xA5\x04\xD7]\f\x87Y\xC1\xFCs\xFA1 \xC86 \x1E\x87">] > tx.to_payload.bth
=> "0100000002f7bd5225dbac8dc91d69a7484877398556f074324296207729f6aefe68b6a7070200000000fffffffff7bd5225dbac8dc91d69a7484877398556f074324296207729f6aefe68b6a7070300000000ffffffff0400000000000000000a6a084f410100020a1e00580200000000000017a914c05e8e53c28ba0404f2945478fd155a353c4e15187580200000000000017a9148caeeda504d75d0c8759c1fc73fa3120c836201e87b82e0f000000000017a9148caeeda504d75d0c8759c1fc73fa3120c836201e8700000000"
>